--<<<
format debug "--  Compiling Animation Class . . .\n" undefined undefined

function hideSprite	 aData theTarget thePlayer->
(
	hide theTarget
)
function showSprite	 aData theTarget thePlayer->
(
	show theTarget
)

function loopMe aData theTarget thePlayer->
(
	gotoBegin thePlayer
)

class Animation(ActionListPlayer)
inst vars
	autoStart
	changeCastScript
	moveCastScript
	fps
end

method changeRate self {class Animation} newValue->
(
	self.rate := newValue
)

method init self {class Animation} #rest args #key lingo: dirInfo: currScene:
->(
	local tFrame := findSXKey(lingo,"firstFrame")
	local fNum := tFrame as integer
	local firstFrame
	if fNum = 0 then (
		firstFrame := frameFromLabel(tFrame, dirInfo)
	) else (
		firstFrame := fNum
	)
	tFrame := findSXKey(lingo,"lastFrame")
	fNum := tFrame as integer
	local lastFrame
	if fNum = 0 then (
		lastFrame := frameFromLabel(tFrame, dirInfo)
	) else (
		lastFrame := fNum
	)
	local tVal := findSXKey(lingo,"firstChannel")
	local firstChannel := tVal as integer
	local tVal := findSXKey(lingo,"lastChannel")
	local lastChannel := tVal as integer
	format debug "Animation: Channel %1 thru %2 of frame %3 thru %4\n" \
					#(firstChannel, lastChannel, firstFrame, lastFrame ) \
					#(@unadorned, @unadorned, @unadorned, @unadorned)
	self.autoStart := (findSXKey(lingo,"autoStart") = "yes")
	local looped := (findSXKey(lingo,"looped") = "yes")
	local sndChan := findSXKey(lingo,"sndChannel")
	local useSound := (sndChan <> undefined) 
	if sndChan = undefined then (
		sndChan := 1
	) else (
		sndChan := (sndChan as integer)
	)
	local sliderName := findSXKey(lingo,"slider")
	local myActions := new ActionList
	local initialTargets := #()
	local score := dirInfo[@score]
	local cast := dirInfo[@cast]
	local frame := score[firstFrame]
	local fps := frame[@tempoChannel][@tempo]
	if fps = 0 do fps := dirInfo[@defaultFPS]
	self.fps := fps
	apply nextMethod self actionList:myActions scale:(fps) targetCount:((lastChannel - firstChannel) + 1) args
	
	local spriteArray := frame[@spriteChannels]
	local castNum, sprite, relChan, relFrame, currTarget, changed
	local workArray := new array
	for c := firstChannel to lastChannel do (
		relChan := (c - firstChannel) + 1
		local currentTargetCast := undefined
		local currentState := @unknown
		for f := firstFrame to lastFrame do (
			relFrame := (f - firstFrame) + 1
			frame := score[f]
			if c = firstChannel  and useSound do ( -- 1st time thru check soundChannel also
				local sndCast := frame[@soundChannels][sndChan]
				if sndCast <> 0 do (
					append myActions (new PlaySndAction sndStream:cast[sndCast] buffer:(100) targetNum:0 time:1)
					format debug "PlaySndAction for sound: %*\n" sndCast @unadorned
				)
			)
			sprite := frame[@spriteChannels][c]
			castNum := sprite[@castIndex]
			changed := frame[@changeArray][c] or f = firstFrame
			if changed do (
				local actionRequested := @none
				if castNum <> 0 then (
					if currentTargetCast = castNum then (
						if currentState = @hidden do (
							actionRequested := @show
						)
					) else if currentTargetCast = undefined then (
						currentTargetCast := castNum
						actionRequested := @initialize
					) else (
						actionRequested := @change
					)
					currentState := @visible
				) else (
					if currentState = @visible do (
						actionRequested := @hide
						currentState := @hidden
					)
				)
				local newAction := undefined
				case actionRequested of
					@initialize:
						(
						local currTarget := cast[castNum]
						currTarget.x := sprite[@x]
						currTarget.y := sprite[@y]
						local sten := currTarget.boundary
						case (sprite[@ink]) of
							@invisible:	(
								sten.invisibleColor	:= whiteColor
								sten.matteColor 	:= undefined
								)
							@matte:	(
								sten.invisibleColor := undefined
								sten.matteColor		:= whiteColor
								)
							@copy:		sten.invisibleColor := sten.matteColor := undefined
						end --case
						prepend currScene currTarget
						self.targets[relChan] := currTarget
						)
					@show:
						(
						newAction := new ScriptAction script: showSprite targetnum:relChan time:relFrame
						)
					@hide:
						(
						newAction := new ScriptAction script: hideSprite targetnum:relChan time:relFrame
						)
					@change:
						(
						local inks := #(@invisible:undefined,@matte:undefined)
						if sprite[@ink] = @invisible do setOne inks @invisible whiteColor
						if sprite[@ink] = @matte do setOne inks @matte whiteColor
						local newLoc := #(sprite[@x],sprite[@y]) as point
						newAction := new ChangeSpriteAction 	targetnum:relChan \
													time:relFrame \
													target:(cast[castNum]) \
													inks:inks \
													location:newLoc
						)
				end --case
				if newAction <> undefined do append myActions newAction 
			)
		)
	)
	if looped do (
		append myActions (new ScriptAction script:loopMe targetNum:0 time:( lastFrame - firstFrame +1))
	)
	if sliderName <> undefined do (
		local sliderList := chooseAll currScene (obj type-> isAKindOf obj type) Slider
		local connectTo := chooseOne sliderList (obj idValue-> obj.id = idValue) sliderName
		if connectTo <> empty do (
			connect connectTo values:#(0,2) target:self changeMethod:changeRate
			setCurrValue connectTo 1
		)
	)
	return self
)

method xSetter self {class Animation} xValue->
(
	"xSetter ignored by Animation"
)
method ySetter self {class Animation} xValue->
(
	"ySetter ignored by Animation"
)
method boundaryGetter self {class Animation}->
(
	return undefined
)
#(Animation, #("autoStart"), #("initialTargetsGetter"))
-->>>
